package com.eidetic.storage.db;
import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.eidetic.note.INote;
import com.eidetic.note.Note;
import com.eidetic.util.exceptions.ItemNotFoundException;

public class NoteStorageAdaptor<T> implements IStorageAdaptor<INote>
{	
	// Database field names
	private static final 	String				FIELD_ID 			= "_id";
	private static final	String				FIELD_PHOTO_PATH	= "photoPath";
	private static final 	String				FIELD_CAPTION		= "caption";
	private static final	String				FIELD_DATE_CREATED	= "dateCreated";
	private static final	String				FIELD_DATE_DUE		= "dateDue";
	
	// Database result column indices 
	private static final	int					COL_ID				= 0;
	private static final	int					COL_PHOTO_PATH		= 1;
	private static final	int					COL_CAPTION			= 2;
	private static final	int					COL_DATE_DUE		= 3;
	private static final	int					COL_DATE_CREATED	= 4;
	
	// Database timestamp formatting
	private static final	String				TIMEF				="yyyyMMddHHmmss";
	private static final	SimpleDateFormat 	dateFormat 			= new SimpleDateFormat(TIMEF);
	
	private final 			String 				TABLE;
	private final 			SQLiteDatabase 		database;
	
	public NoteStorageAdaptor(SQLiteDatabase database, String table)
	{
		this.database 	= database;
		this.TABLE 		= table;
	}
	
	// TODO Cache results
	@Override
	public INote fectch(int id) throws ItemNotFoundException
	{
		INote 	note;
		Cursor 	result;
		
		result = database.query(TABLE, null, FIELD_ID+"="+id, null, null, null, null);
		
		if (result == null)
			throw new ItemNotFoundException(id);
		
		result.moveToFirst();
		
		note = loadFromResult(result);
		return note;
	}
	
	public Collection<INote> fetchAll()
	{
		Collection<INote> notes = new ArrayList<INote>();
		
		Cursor result = database.query(TABLE, null, null, null, null, null, null);
		result.moveToFirst();
		
		while (result != null)
		{
			notes.add(loadFromResult(result));
			result.moveToNext();
		}
		
		return notes;
	}

	@Override
	public long create(INote note)
	{
		
		long id = database.insert(TABLE, null, noteToContent(note));
		
		if (id == -1)
		{
			// FIXME Throw some exception here
		} 
		
		note.setId(id);
		return id;
	}

	@Override
	public void update(INote obj)
	{
		// TODO Auto-generated method stub
	}

	@Override
	public void delete(INote obj)
	{
		// TODO Auto-generated method stub
	}
	
	private ContentValues noteToContent(INote note)
	{
		ContentValues values = new ContentValues();
		
		if (note.getId() != -1)
			values.put(FIELD_ID, note.getId());
		
		values.put(FIELD_PHOTO_PATH, 	note.getPhoto().toURI().toString());
		values.put(FIELD_CAPTION, 		note.getCaption());
		values.put(FIELD_DATE_CREATED, 	dateFormat.format(note.getDateCreated()));
		values.put(FIELD_DATE_DUE, 		dateFormat.format(note.getDateDue()));
		
		return values;
	}
	
	private INote loadFromResult(Cursor result)
	{
		String 	caption	= result.getString(COL_CAPTION);
		File 	picture	= new File(result.getString(COL_PHOTO_PATH));
		Date 	dateDue;
		Date 	dateCreated;
		
		try
		{
			dateDue 	= dateFormat.parse(result.getString(COL_DATE_DUE));
			dateCreated = dateFormat.parse(result.getString(COL_DATE_CREATED)); 
		} 
		
		catch (ParseException e)
		{
			// FIXME Throw some sort of `Database corrupted` exception here
			e.printStackTrace();
			return null;
		}
		
		INote note		= new Note(picture);
		note.setId(result.getLong(COL_ID));
		note.setCaption(caption);
		note.setDateDue(dateDue);
		note.setDateCreated(dateCreated);
		
		return note;		
	}
}
